package com.oner365.test.stream;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ListDemo {
  
  private static final Logger LOGGER = LoggerFactory.getLogger(ListDemo.class);
  
  public static void main(String[] args) {
    LOGGER.info("int :{}",IntStream.range(0, 5).map(i -> 0).findFirst().orElse(0));
    parallelDistinct();
    LOGGER.info("=============map============");
    parallelDistinctMap();
    LOGGER.info("=============map test============");
    parallelDistinctMapTest();
    LOGGER.info("=============map run============");
    parallelDistinctMapRun();
  }
  
  public static List<String> getList(int size,int sleepTime) {
    List<String> list = new ArrayList<String>();
    Random r = new Random();
    try {
      TimeUnit.SECONDS.sleep(sleepTime);
    } catch (InterruptedException e) {
      LOGGER.error("error",e);
    }
    for(int i=0;i<size;i++) {
      list.add(String.valueOf(r.nextInt(10)));
    }
    return list;
  }
  
  public static Map<String,String> getMap(int size,int sleepTime){
    Map<String,String> map = new HashMap<String,String>();
    Random r = new Random();
    try {
      TimeUnit.SECONDS.sleep(sleepTime);
    } catch (InterruptedException e) {
      LOGGER.error("error",e);
    }
    for(int i=0;i<size;i++) {
      map.put(String.valueOf(i), String.valueOf(r.nextInt(10)));
    }
    return map;
  }
  
  /**
   *  并行及去重
   */
  public static void parallelDistinct() {
    LOGGER.info("parallelDistinct");
    long start = System.currentTimeMillis();
    List<String> result = new ArrayList<String>();
    List<Runnable> list = new ArrayList<Runnable>() {
      private static final long serialVersionUID = 1L;
      {
        add(() -> result.addAll(getList(5,1)));
        add(() -> result.addAll(getList(6,2)));
        add(() -> result.addAll(getList(5,3)));
        add(() -> result.addAll(getList(8,4)));
      }
    };
    list.parallelStream().forEach(task -> task.run());
    List<String> result1 = result.stream().distinct().collect(Collectors.toList());
    result1.stream().forEach(s -> LOGGER.info(s));
    LOGGER.info("用时:{}", (System.currentTimeMillis() - start) / 1000);
  }
  
  /**
   *  并行及去重
   */
  public static void parallelDistinctMapTest() {
    LOGGER.info("parallelDistinctMapTest");
    long start = System.currentTimeMillis();
    List<String> result = new ArrayList<String>();
    Map<String,String> map = getMap(5,2);
    map.keySet().parallelStream().forEach(key->result.add(map.get(key)));
    List<Runnable> list = new ArrayList<Runnable>() {
      private static final long serialVersionUID = 1L;
      {
        map.keySet().stream().forEach(key -> {
          add(() -> result.add(map.get(key)));
        });
      }
    };
    Runnable runnable = () ->{
      try {
        TimeUnit.SECONDS.sleep(2);
      } catch (InterruptedException e) {
        LOGGER.error("error:",e);
      }
      LOGGER.info("runnable.run()");
    };
    list.add(runnable);
    LOGGER.info("list.size:{}",list.size());
    list.parallelStream().forEach(task -> task.run());
    List<String> result1 = result.stream().distinct().collect(Collectors.toList());
    LOGGER.error("result size:{}",result.size());
    result1.parallelStream().forEach(s -> LOGGER.info(s));
    LOGGER.info("用时:{}", (System.currentTimeMillis() - start) / 1000);
  }
  
  /**
   *  并行及去重
   */
  public static void parallelDistinctMapRun() {
    LOGGER.info("parallelDistinctMapTest");
    long start = System.currentTimeMillis();
    List<String> result = new ArrayList<String>();
    Map<String,String> map = getMap(5,2);
    map.keySet().parallelStream().forEach(key->{
      LOGGER.info("看线程号 key:{}",key);
      result.add(map.get(key));
    });
    List<String> result1 = result.stream().distinct().collect(Collectors.toList());
    LOGGER.error("result size:{}",result.size());
    result1.parallelStream().forEach(s -> LOGGER.info(s));
    LOGGER.info("用时:{}", (System.currentTimeMillis() - start) / 1000);
  }

  
  /**
   *  并行及去重
   */
  public static void parallelDistinctMap() {
    LOGGER.info("parallelDistinctMap");
    long start = System.currentTimeMillis();
    List<String> result = new ArrayList<String>();
    List<Runnable> list = new ArrayList<Runnable>() {
      private static final long serialVersionUID = 1L;
      {
        add(() -> result.addAll(getMap(5,1).values()));
        add(() -> result.addAll(getMap(6,2).values()));
        add(() -> result.addAll(getMap(7,3).values()));
        add(() -> result.addAll(getMap(8,4).values()));
      }
    };
    list.parallelStream().forEach(task -> task.run());
    List<String> result1 = result.stream().distinct().collect(Collectors.toList());
    result1.stream().forEach(s -> LOGGER.info(s));
    LOGGER.info("用时:{}", (System.currentTimeMillis() - start) / 1000);
  }

}
